﻿using System;
using System.Threading;
using LiveLabs.Logging;
using LiveLabs.Logging.Logs;

class Program
{
    static public readonly Logger logger;

    static Program()
    {
        Log log = new LockingLog(new TimedRollingLog("core_timedrollinglog_stress.log"));

        Settings set = new Settings();
        set.DefaultLog = log;
        set.DefaultLogLevel = LogLevel.Debug;

        logger = new Logger(typeof(Program), log, set);
    }

    static void Main(string[] args)
    {
        logger.Inform("Stress Test Starting up");

        int procCount = Environment.ProcessorCount * 2;
        logger.Inform(() => "Starting up " + procCount + " threads to write to logger at same time");

        Thread[] threads = new Thread[procCount];
        EventWaitHandle[] events = new EventWaitHandle[procCount];
        EventWaitHandle shutdown = new EventWaitHandle(false, EventResetMode.ManualReset);

        for(int i = 0; i < threads.Length; ++i)
        {
            events[i] = new EventWaitHandle(false, EventResetMode.ManualReset);
            threads[i] = new Thread(Program.Log);
            threads[i].Name = "Thread #" + i;
            threads[i].Start(new [] { events[i], shutdown });
        }

        Console.Out.WriteLine("Press Enter to end");
        Console.ReadLine();

        shutdown.Set();

        WaitHandle.WaitAll(events);

        logger.Inform("Stress Test Shutting down");
    }

    static void Log(object state)
    {
        EventWaitHandle finish = ((EventWaitHandle[])state)[0];
        EventWaitHandle stop = ((EventWaitHandle[])state)[1];

        Random rnd = new Random();
        do
        {
            // between 150 and 500 milliseconds
            int sleep = rnd.Next(150, 500);

            if (stop.WaitOne(sleep))
            {
                break;
            }

            logger.Inform("A simple information message");
            logger.Warn(() => "A simple warning");

            try
            {
                throw new ArgumentOutOfRangeException("bogus", 10, "bogus is out of range");
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }
        while (true);

        finish.Set();
    }
}
